#include "PreCompile.hpp"
#include "ErrorListener.hpp"
#include "Module.hpp"
#include "LibBuildNGInit.hpp"

namespace BuildNG
{
  void ErrorLocationInfo::set_not_specified()
  {
    file_name = "";
    line_number = -1;
    column_number = -1;
  }

  ////////
  // ErrorListener
  ErrorListener::ErrorListener()
  {
    assert_libbuildng_initialized();
  }

  ErrorListener::~ErrorListener()
  {
  }

  /////////////
  // StdErrorListener
  void StdErrorListener::begin_build_module(Glib::RefPtr<Module> module)
  {
    std::cout << "Building module \"" + module->get_name() << "\"" << std::endl;
  }

  void StdErrorListener::end_build_module(Glib::RefPtr<Module> module)
  {
    std::cout << "---" << std::endl;
  }

  void StdErrorListener::report_error(const ErrorLocationInfo &location_info,const Glib::ustring &msg)
  {
    std::cerr << location_info.file_name << ":";
    if(location_info.line_number != -1)
      std::cerr << location_info.line_number << ":";
    if(location_info.column_number != -1)
      std::cerr << location_info.column_number << ":";
    std::cout << "error: " << msg << std::endl;
  }

  void StdErrorListener::report_warning(const ErrorLocationInfo &location_info,const Glib::ustring &msg)
  {
    std::cerr << location_info.file_name << ":";
    if(location_info.line_number != -1)
      std::cerr << location_info.line_number << ":";
    if(location_info.column_number != -1)
      std::cerr << location_info.column_number << ":";
    std::cout << "warning: " << msg << std::endl;
  }

  Glib::RefPtr<StdErrorListener> StdErrorListener::create()
  {
    return Glib::RefPtr<StdErrorListener>(new StdErrorListener);
  }

  //////////////
  // DOMErrorListener
  DOMErrorListener::DOMErrorListener(int flags)
    : flags(flags)
  { 
  }

  DOMErrorListener::~DOMErrorListener()
  {
  }

  Glib::RefPtr<DOMErrorListener> DOMErrorListener::create(int flags)
  {
    return Glib::RefPtr<DOMErrorListener>(new DOMErrorListener(flags));
  }

  void DOMErrorListener::begin_build_module(Glib::RefPtr<Module> module)
  {
    cur_module = Glib::RefPtr<ModuleReport>(new ModuleReport);
    cur_module->module = module;
    module_reports.push_back(cur_module);
  }

  void DOMErrorListener::end_build_module(Glib::RefPtr<Module> module)
  {
    cur_module.clear();
  }

  void DOMErrorListener::report_error(const ErrorLocationInfo &location_info,const Glib::ustring &msg)
  {
    assert(cur_module);

    Error cur_error;
    cur_error.error_type = ErrorType_Error;
    cur_error.location_info = location_info;
    cur_error.msg = msg;
    cur_module->errors.push_back(cur_error);
  }

  void DOMErrorListener::report_warning(const ErrorLocationInfo &location_info,const Glib::ustring &msg)
  {
    assert(cur_module);

    if(flags & Flag_IgnoreWarnings)
      return;

    Error cur_error;
    cur_error.error_type = ErrorType_Warning;
    cur_error.location_info = location_info;
    cur_error.msg = msg;
    cur_module->errors.push_back(cur_error);
  }
}
